package oop.ex2.main;

import java.io.IOException;
import java.util.regex.*;

import oop.ex2.tools.CheckType;
import oop.ex2.tools.TextProcessor;

/**
 * 
 * @author yossavi
 *
 */
public class CorrectnessAndHandle {
	
	/**
	 * gets a line that contains variable declaration
	 * checks if it's correct and return it as Variable object 
	 * @param line- line of variable declaration to process
	 * @param isParam- true if the line is parameter
	 * @return the variable as object "Variable"
	 * @throws compilationException
	 */
	public static Variable handleVariable(String line, boolean isParam) throws compilationException{
		// pattern for variable declaration 
		Pattern pattern = Pattern.compile("("+CheckType.FINAL+" )?(.*) (([a-zA-Z]\\w*)|(_[a-zA-Z]\\w*))((=)(.*))?$");
		Matcher matcher = pattern.matcher(line);
		
		if (matcher.find()) {
			boolean isFinal=false;
			if (matcher.group(1)!=null)
				isFinal=true;
			// checks variable type
			if (!CheckType.isVariableType(matcher.group(2)))
				throw new UnknownTypeException("UnKnown variable type");
			// checks variable name
			if (!CheckType.isValidVariableName(matcher.group(3)))
				throw new UnsupportedNameException("Unsupported variable name");
			// checks if a parameter got value
			if (isParam && matcher.group(8)!=null)
				throw new UnknownStatementException("parameter can't get value");

			Variable tempVariable;
			if (isParam)
				tempVariable = new Variable(isFinal, matcher.group(2), matcher.group(3));
			else
				tempVariable = new Variable(isFinal, matcher.group(2), matcher.group(3), matcher.group(8));
			
			return tempVariable;
		}
		throw new UnknownStatementException("UnKnown variable declarition");
	}
	
	/**
	 * gets a line that contains method declaration
	 * checks if it's correct saves is whole body
	 * and return it as Block object 
	 * @param line - line of method declaration to process
	 * @return the method as object "Block"
	 * @throws compilationException
	 * @throws IOException
	 */
	public static Block handleMethod(String line) throws compilationException, IOException {
		// pattern for method declaration
		Pattern pattern = Pattern.compile("(.*) ([a-zA-Z]\\w*)\\((.*)\\)\\{");
		Matcher matcher = pattern.matcher(line);
		
		if (matcher.find()) {
			// checks the method return type
			if (!CheckType.isMethodType(matcher.group(1)))
				throw new UnknownTypeException("UnKnown method type");
			// checks the method return type
			if (!CheckType.isValidMethodName(matcher.group(2)))
				throw new UnsupportedNameException("Unsupported method name");
			
			Block tempMethod= new Block (matcher.group(1),matcher.group(2));
			
			String[] parameters =  matcher.group(3).split(",");
			// run over the parameters
			for (String p: parameters) {
				if (!p.equals(""))
					// add the parameter to the method
					tempMethod.addParameter(handleVariable(p, true));
			}
			
			// saves the body of the method as Strings in the method
			boolean isCloesd=false;
			int bracketCounter=1;
			 do {
				Sjavac.nextLine();
				TextProcessor.cleanCode();
				if(Sjavac.line.matches(".*\\{")){
					bracketCounter++;
				}
				if (Sjavac.line.matches("\\}.*")) {
					bracketCounter--;
				}
				if (bracketCounter==0) {	
					isCloesd=true;
					break;
				}
				tempMethod.addLine(Sjavac.line);
			} while (Sjavac.line!=null);
			if (!isCloesd)
				throw new UnClosedStatementException("Uncloesd method");
			Sjavac.nextLine();
			
			return tempMethod;
		} 
		throw new UnknownStatementException("UnKnown method declarition");
	}
	
}
